package com.zhiyin.seal.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiyin.seal.anno.OperateLog;
import com.zhiyin.seal.constant.SealResponseCodeConst;
import com.zhiyin.seal.entity.bo.*;
import com.zhiyin.seal.entity.dto.*;
import com.zhiyin.seal.entity.vo.*;
import com.zhiyin.seal.service.*;
import com.zhiyin.seal.util.BeanUtil;
import com.zhiyin.seal.util.DateUtil;
import com.zhiyin.seal.util.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 印章业务控制器
 */
@RestController
@RequestMapping("/seal")
public class SealController {

    @Autowired
    SealService sealService;

    @Autowired
    UserService userService;

    @Autowired
    CompanyService companyService;

    @Autowired
    ApprovalService approvalService;

    @Autowired
    ElectronicFenceService electronicFenceService;

    @Autowired
    SystemService systemService;

    @Autowired
    ApplyService applyService;

    @GetMapping("/info")
    public ResponseDTO<SealVo> getSeal(@RequestParam Long id){
        // 查询印章
        SealBo sealBo = sealService.getSeal(id);
        SealVo sealVo = BeanUtil.copy(sealBo,SealVo.class);
        // 判断是否过期
        if(sealVo.getServiceTime().getTime() - (new Date()).getTime() <=0){
            sealVo.setExpireStatus(true);
        } else {
            sealVo.setExpireStatus(false);
        }
        // 查询创建人
        UserBo userBo = userService.getUserInfoById(sealBo.getCreateUser());
        UserVo userVo = BeanUtil.copy(userBo,UserVo.class);
        sealVo.setCreateUserVo(userVo);
        // 查找所属公司
        CompanyBo companyBo = companyService.getCompanyById(sealBo.getCompanyId());
        CompanyVo companyVo = BeanUtil.copy(companyBo,CompanyVo.class);
        sealVo.setCompanyVo(companyVo);
        // 查找所在部门
        Long departmentId = sealVo.getDepartmentId();
        if(departmentId == null)
            departmentId = 0L;
        CompanyDepartmentBo departmentBo = companyService.getDepartmentById(departmentId);
        CompanyDepartmentVo departmentVo = BeanUtil.copy(departmentBo,CompanyDepartmentVo.class);
        sealVo.setDepartmentVo(departmentVo);

        return ResponseDTO.succData(sealVo);
    }

    @GetMapping("/infobymac")
    public ResponseDTO<SealVo> getSealByMac(@RequestParam String mac){
        // 查询印章
        SealBo sealBo = sealService.getSealByMac(mac);
        // 如果为空，直接返给页面
        if(sealBo == null)
            return ResponseDTO.succData(null);

        SealVo sealVo = BeanUtil.copy(sealBo,SealVo.class);
        // 判断是否过期
        if(sealVo.getServiceTime().getTime() - (new Date()).getTime() <=0){
            sealVo.setExpireStatus(true);
        } else {
            sealVo.setExpireStatus(false);
        }
        // 查询创建人
        UserBo userBo = userService.getUserInfoById(sealBo.getCreateUser());
        UserVo userVo = BeanUtil.copy(userBo,UserVo.class);
        sealVo.setCreateUserVo(userVo);
        // 查找所属公司
        CompanyBo companyBo = companyService.getCompanyById(sealBo.getCompanyId());
        CompanyVo companyVo = BeanUtil.copy(companyBo,CompanyVo.class);
        sealVo.setCompanyVo(companyVo);

        return ResponseDTO.succData(sealVo);
    }

    @GetMapping("/list")
    public ResponseDTO<List<SealVo>> getCompanySealList(@RequestParam Long companyId){
        List<SealBo> sealBoList = sealService.getCompanySealList(companyId);
        List<SealVo> sealVoList = BeanUtil.copyList(sealBoList,SealVo.class);
        Date now = new Date();
        for (SealVo sealVo : sealVoList) {
            // 判断是否过期
            if(sealVo.getServiceTime().getTime() - now.getTime() <=0){
                sealVo.setExpireStatus(true);
            } else {
                sealVo.setExpireStatus(false);
            }
            // 查找所在部门
            Long departmentId = sealVo.getDepartmentId();
            if(departmentId == null)
                departmentId = 0L;
            CompanyDepartmentBo departmentBo = companyService.getDepartmentById(departmentId);
            CompanyDepartmentVo departmentVo = BeanUtil.copy(departmentBo,CompanyDepartmentVo.class);
            sealVo.setDepartmentVo(departmentVo);
        }

        return ResponseDTO.succData(sealVoList);
    }

    @GetMapping("/list2")
    public ResponseDTO<List<SealVo>> getCompanySealList2(@RequestParam Long companyId){
        List<SealBo> sealBoList = sealService.getCompanySealList2(companyId);
        List<SealVo> sealVoList = BeanUtil.copyList(sealBoList,SealVo.class);
        Date now = new Date();
        for (SealVo sealVo : sealVoList) {
            // 判断是否过期
            if(sealVo.getServiceTime().getTime() - now.getTime() <=0){
                sealVo.setExpireStatus(true);
            } else {
                sealVo.setExpireStatus(false);
            }
            // 查找所在部门
            Long departmentId = sealVo.getDepartmentId();
            if(departmentId == null)
                departmentId = 0L;
            CompanyDepartmentBo departmentBo = companyService.getDepartmentById(departmentId);
            CompanyDepartmentVo departmentVo = BeanUtil.copy(departmentBo,CompanyDepartmentVo.class);
            sealVo.setDepartmentVo(departmentVo);

            UserBo userBo = userService.getUserInfoByIdAndCompany(sealVo.getCreateUser(),sealVo.getCompanyId());
            sealVo.setCreateUserVo(BeanUtil.copy(userBo,UserVo.class));
            if(sealVo.getDeleteUser() != null){
                userBo = userService.getUserInfoByIdAndCompany(sealVo.getDeleteUser(),sealVo.getCompanyId());
                sealVo.setDeleteUserVo(BeanUtil.copy(userBo,UserVo.class));
            }
        }

        return ResponseDTO.succData(sealVoList);
    }

    @GetMapping("/list/all")
    public ResponseDTO<List<SealVo>> getAllSealList(@RequestParam String keywords){
        List<SealVo> sealVoList = BeanUtil.copyList(sealService.getAllSealList(keywords),SealVo.class);
        List<Long> companyIdList = Lists.newArrayList();
        companyIdList.add(0l);
        List<Long> userIdList = Lists.newArrayList();
        userIdList.add(0l);
        Date now = new Date();
        for (SealVo sealVo : sealVoList) {
            // 判断是否过期
            if(sealVo.getServiceTime().getTime() - now.getTime() <=0){
                sealVo.setExpireStatus(true);
            } else {
                sealVo.setExpireStatus(false);
            }
            companyIdList.add(sealVo.getCompanyId());
            userIdList.add(sealVo.getCreateUser());
        }
        List<CompanyBo> companyBoList = companyService.getCompanyListByIds(companyIdList);
        List<UserBo> userBoList = userService.getUserListByIds(userIdList);
        Map<Long,CompanyBo> companyBoMap = Maps.newHashMap();
        Map<Long,UserBo> userBoMap = Maps.newHashMap();
        for(CompanyBo companyBo : companyBoList){
            companyBoMap.put(companyBo.getId(),companyBo);
        }
        for(UserBo userBo : userBoList){
            userBoMap.put(userBo.getId(),userBo);
        }
        for (SealVo sealVo : sealVoList) {
//            sealVo.setCompanyVo(BeanUtil.copy(companyBoMap.get(sealVo.getCompanyId()),CompanyVo.class));
//            sealVo.setCreateUserVo(BeanUtil.copy(userBoMap.get(sealVo.getCreateUser()),UserVo.class));
            UserBo userBo = userBoMap.get(sealVo.getCreateUser());
            if(userBo != null){
                sealVo.setUserName(userBo.getNickName());
                sealVo.setPhoneNumber(userBo.getPhoneNumber());
            }
            CompanyBo companyBo = companyBoMap.get(sealVo.getCompanyId());
            if(companyBo != null){
                sealVo.setCompanyName(companyBo.getName());
            }
        }

        return ResponseDTO.succData(sealVoList);
    }

    @OperateLog(description = "修改服务费时间")
    @PostMapping("/service/time/update")
    public ResponseDTO<Boolean> updateSealServiceTime(@RequestBody SealDTO sealDTO){
        return ResponseDTO.succData(sealService.updateSealServiceTime(sealDTO.getId(),sealDTO.getNewServiceTime()));
    }

    @GetMapping("/apply/list")
    public ResponseDTO<List<SealVo>> getApplySealList(@RequestParam Long userId){
        List<SealBo> sealBoList = sealService.getApplySealList(userId);
        List<SealVo> sealVoList = Lists.newArrayList();
        if(sealBoList != null){
            CompanyBo companyBo = companyService.getUserDefaultCompany(userId);
            if(companyBo != null){
                sealBoList.forEach(sealBo -> {
                    // 筛选用户默认公司的印章
                    if(sealBo.getCompanyId().equals(companyBo.getId())){
                        SealVo sealVo = BeanUtil.copy(sealBo,SealVo.class);
                        sealVoList.add(sealVo);
                    }
                });
            }
        }

        Date now = new Date();
        for (SealVo sealVo : sealVoList) {
            // 判断是否过期
            if(sealVo.getServiceTime().getTime() - now.getTime() <=0){
                sealVo.setExpireStatus(true);
            } else {
                sealVo.setExpireStatus(false);
            }
        }

        return ResponseDTO.succData(sealVoList);
    }

    @GetMapping("/my/list")
    public ResponseDTO<List<SealVo>> getMySealList(@RequestParam Long userId){
        List<SealVo> sealVoList = BeanUtil.copyList(sealService.getMySealList(userId),SealVo.class);
        Date now = new Date();
        for (SealVo sealVo : sealVoList) {
            // 判断是否过期
            if(sealVo.getServiceTime().getTime() - now.getTime() <=0){
                sealVo.setExpireStatus(true);
            } else {
                sealVo.setExpireStatus(false);
            }
        }

        return ResponseDTO.succData(sealVoList);
    }

    @PostMapping("/add")
    public ResponseDTO<Boolean> addSeal(@RequestBody AddSealDTO sealDTO){
        // 判断部门是否为空
        if(sealDTO.getDepartmentId() == null){
            sealDTO.setDepartmentId(0l);
        }
        // 判断人脸拍照是否为空
        if(sealDTO.getFacePhoto() == null){
            sealDTO.setFacePhoto(true);
        }
        // 判断盖章拍照是否为空
        if(sealDTO.getForcePhotograph() == null){
            sealDTO.setForcePhotograph(false);
        }
        // 注册设备
        HttpUtil.doGet("https://zhiyinseal.cn/smartsealservice/system/device/register?sdkId=8&mac=" + sealDTO.getMac());
        // 是否为替换印章
        SealReplaceBo sealReplaceBo = sealService.getSealReplaceByMac(sealDTO.getMac());
        if(sealReplaceBo != null){
            return ResponseDTO.wrap(SealResponseCodeConst.ALREADY_REPLACE);
        }
        // 判断是否添加
        SealBo sealBo = sealService.getSealByMac(sealDTO.getMac());
        if(sealBo != null){
            // 判断印章使用状态
            if(sealBo.getEnableFlag()){
                return ResponseDTO.wrap(SealResponseCodeConst.ALREADY_BIND);
            } else {
                // 更新印章信息
                sealBo.setName(sealDTO.getName());
                sealBo.setCreateUser(sealDTO.getCreateUser());
                sealBo.setForcePhotograph(sealDTO.getForcePhotograph());
                sealBo.setFacePhoto(sealDTO.getFacePhoto());
                sealBo.setEnableFlag(true);
                sealBo.setStatus(2);
                sealBo.setCompanyId(sealDTO.getCompanyId());
                sealBo.setDepartmentId(sealDTO.getDepartmentId());
                sealService.updateSeal(sealBo);

                // 清空审批流
                approvalService.removeApprovalProcessBySealId(sealBo.getId());
                // 清空电子围栏
                electronicFenceService.removeElectronicFenceBySealId(sealBo.getId());
                // 清除印章管理员
                sealService.removeSealAdmin(sealBo.getId());
            }
        } else {
            sealBo = BeanUtil.copy(sealDTO,SealBo.class);
            // 赋值服务费时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_MONTH,7);
            Date serviceTime = calendar.getTime();
            sealBo.setServiceTime(serviceTime);
            // 插入印章
            sealService.addSeal(sealBo);
        }

        // 更新印章公司关系
        if(sealBo != null){
            sealBo = sealService.getSealByMac(sealDTO.getMac());
            sealService.addSealCompany(sealBo);
        }
        return ResponseDTO.succData(true);
    }

    @PostMapping("/replace")
    public ResponseDTO<Boolean> replaceSeal(@RequestBody ReplaceSealDTO replaceSealDTO){
        // 判断是否注册
        SdkDeviceBo sdkDeviceBo = systemService.getSdkDevice(replaceSealDTO.getMac());
        if(sdkDeviceBo != null){
            return ResponseDTO.wrap(SealResponseCodeConst.FORBIDDEN);
        }
        // 判断新印章是否为替换过的印章
        SealReplaceBo sealReplaceBo = sealService.getSealReplaceByMac(replaceSealDTO.getMac());
        if(sealReplaceBo != null){
            return ResponseDTO.wrap(SealResponseCodeConst.ALREADY_REPLACE);
        }
        // 判断新印章是否添加过
        SealBo sealBo = sealService.getSealByMac(replaceSealDTO.getMac());
        if(sealBo != null){
            return ResponseDTO.wrap(SealResponseCodeConst.ALREADY_BIND);
        }
        // 查找老印章
        sealBo = sealService.getSeal(replaceSealDTO.getSealId());
        if(sealBo != null){
            // 判断新印章和老印章是否为同一个章
            if(sealBo.getMac().equals(replaceSealDTO.getMac())){
                return ResponseDTO.wrap(SealResponseCodeConst.NO_REPLACE);
            }
            // 插入印章替换日志
            sealReplaceBo = new SealReplaceBo();
            sealReplaceBo.setNewMac(replaceSealDTO.getMac());
            sealReplaceBo.setOldMac(sealBo.getMac());
            sealReplaceBo.setCreateUser(replaceSealDTO.getCreateUser());
            Boolean result =sealService.addSealReplace(sealReplaceBo);

            if(result){
                // 设置新的mac地址
                sealBo.setMac(replaceSealDTO.getMac());
                // 更新
                sealService.updateSeal(sealBo);
                // 注册设备
                HttpUtil.doGet("https://zhiyinseal.cn/smartsealservice/system/device/register?sdkId=8&mac=" + replaceSealDTO.getMac());
            }
        } else {
            return ResponseDTO.wrap(SealResponseCodeConst.NOT_EXISTS);
        }

        return ResponseDTO.succData(true);
    }

    @GetMapping("/update/name")
    public ResponseDTO<Boolean> updateSealName(@RequestParam Long sealId,@RequestParam String name){
        return ResponseDTO.succData(sealService.updateSealName(sealId,name));
    }

    @GetMapping("/update/forcephotograph")
    public ResponseDTO<Boolean> updateSealForcePhotograph(@RequestParam Long sealId,@RequestParam Boolean forcePhotograph){
        return ResponseDTO.succData(sealService.updateSealForcePhotograph(sealId,forcePhotograph));
    }

    @GetMapping("/update/face/photo")
    public ResponseDTO<Boolean> updateSealFacePhoto(@RequestParam Long sealId,@RequestParam Boolean facePhoto){
        return ResponseDTO.succData(sealService.updateSealFacePhoto(sealId,facePhoto));
    }

    @GetMapping("/update/department")
    public ResponseDTO<Boolean> updateSealDepartment(@RequestParam Long sealId,@RequestParam Long departmentId){
        return ResponseDTO.succData(sealService.updateSealDepartment(sealId,departmentId));
    }

    @GetMapping("/update/status")
    public ResponseDTO<Boolean> updateSealStatus(@RequestParam Long sealId,@RequestParam Integer status){
        return ResponseDTO.succData(sealService.updateSealStatus(sealId,status));
    }

    @GetMapping("/remove")
    public ResponseDTO<Boolean> removeSeal(@RequestParam Long sealId){
        // 更新印章为不可用
        SealBo sealBo = sealService.getSeal(sealId);
        if(sealBo != null){
            sealBo.setEnableFlag(false);
            sealBo.setStatus(0);
            sealService.updateSeal(sealBo);
            // 移除印章与公司关系
            sealService.removeSealCompanyBySealId(sealId);
            // 清空审批流
            approvalService.removeApprovalProcessBySealId(sealBo.getId());
            // 清空电子围栏
            electronicFenceService.removeElectronicFenceBySealId(sealBo.getId());
            // 清除印章管理员
            sealService.removeSealAdmin(sealBo.getId());
            // 关闭未使用的单据
            applyService.updateApplyCloseBySealId(sealId);
        } else {
            return ResponseDTO.wrap(SealResponseCodeConst.NOT_EXISTS);
        }

        return ResponseDTO.succData(true);
    }

    @GetMapping("/remove2")
    public ResponseDTO<Boolean> removeSeal2(@RequestParam Long userId,@RequestParam Long sealId){
        // 更新印章为不可用
        SealBo sealBo = sealService.getSeal(sealId);
        if(sealBo != null){
            sealBo.setEnableFlag(false);
            sealBo.setStatus(0);
            sealService.updateSeal(sealBo);
            // 移除印章与公司关系
            sealService.removeSealCompany(userId,sealId);
            // 清空审批流
            approvalService.removeApprovalProcessBySealId(sealBo.getId());
            // 清空电子围栏
            electronicFenceService.removeElectronicFenceBySealId(sealBo.getId());
            // 清除印章管理员
            sealService.removeSealAdmin(sealBo.getId());
            // 关闭未使用的单据
            applyService.updateApplyCloseBySealId(sealId);
        } else {
            return ResponseDTO.wrap(SealResponseCodeConst.NOT_EXISTS);
        }

        return ResponseDTO.succData(true);
    }

    @PostMapping("/upload/alarm")
    public ResponseDTO<Boolean> uploadAlarmRecord(@RequestBody AddAlarmRecordDTO alarmRecordDTO){
        AlarmRecordBo alarmRecordBo = BeanUtil.copy(alarmRecordDTO,AlarmRecordBo.class);
        alarmRecordBo.setCreateTime(DateUtil.getDateFromString(alarmRecordDTO.getAlarmTime()));

        return ResponseDTO.succData(sealService.uploadAlarmRecord(alarmRecordBo));
    }

    @GetMapping("/fingerprint/list")
    public ResponseDTO<List<SealFingerprintVo>> getSealFingerprintList(@RequestParam Long companyId, @RequestParam Long sealId){
        List<SealFingerPrintBo> sealFingerPrintBoList = sealService.getFingerprintList(companyId,sealId);
        List<SealFingerprintVo> sealFingerprintVoList = BeanUtil.copyList(sealFingerPrintBoList,SealFingerprintVo.class);
        if(sealFingerprintVoList.size() > 0){
            List<Long> idList = sealFingerprintVoList.stream().map(SealFingerprintVo::getStampUser).collect(Collectors.toList());
            List<UserBo> userBoList = userService.getUserListByIds(idList);
            Map<Long,UserVo> userVoMap = Maps.newHashMap();
            for (UserBo userBo : userBoList) {
                UserVo userVo = BeanUtil.copy(userBo,UserVo.class);
                userVoMap.put(userBo.getId(),userVo);
            }
            for (SealFingerprintVo sealFingerprintVo : sealFingerprintVoList) {
                sealFingerprintVo.setStampUserVo(userVoMap.get(sealFingerprintVo.getStampUser()));
            }
        }

        return ResponseDTO.succData(sealFingerprintVoList);
    }

    @PostMapping("/register/fingerprint")
    public ResponseDTO<Boolean> registerFingerprint(@RequestBody RegisterFingerprintDTO registerFingerprintDTO){
        SealFingerPrintBo sealFingerPrintBo = BeanUtil.copy(registerFingerprintDTO,SealFingerPrintBo.class);
        sealFingerPrintBo.setExpireTime(DateUtil.getDateFromString(registerFingerprintDTO.getExpireTime()));
        return ResponseDTO.succData(sealService.registerFingerprint(sealFingerPrintBo));
    }

    @PostMapping("/modify/fingerprint")
    public ResponseDTO<Boolean> modifyFingerprint(@RequestBody RegisterFingerprintDTO registerFingerprintDTO){
        SealFingerPrintBo sealFingerPrintBo = BeanUtil.copy(registerFingerprintDTO,SealFingerPrintBo.class);
        sealFingerPrintBo.setExpireTime(DateUtil.getDateFromString(registerFingerprintDTO.getExpireTime()));
        return ResponseDTO.succData(sealService.modifyFingerprint(sealFingerPrintBo));
    }

    @GetMapping("/remove/fingerprint")
    public ResponseDTO<Boolean> removeFingerprint(@RequestParam Long id,@RequestParam Long deleteUser){
        return ResponseDTO.succData(sealService.removeFingerprint(id,deleteUser));
    }
}
